<?php

namespace App\Http\Controllers\AgentAdmin;

use App\Exceptions\ApiException;
use App\Http\Controllers\Controller;
use App\Models\AgentUser;
use App\Models\FrontendUser;
use App\Models\Lottery;
use App\Models\LotteryRecord;
use App\Models\LotteryUser;
use App\Utils\UploadHelper;
use Illuminate\Support\Arr;
use Vinlon\Laravel\LayAdmin\Exceptions\AdminException;

class LotteryUserController extends Controller
{
    /** 查询抽奖名单 */
    public function index()
    {
        $query = LotteryUser::query()
            ->where('lottery_id', request()->lottery_id)
            ->with('user')
            ->when(request()->keyword, function ($q) {
                return $q->whereHas('user', function ($q1) {
                    return $q1->where('mobile', 'like', '%' . request()->keyword . '%');
                });
            })->orderByDesc('id');

        return paginate_result($query, function (LotteryUser $user) {
            $user->draw_times = $this->getUserDrawCount($user);

            return $user;
        });
    }

    /** 保存抽奖用户 */
    public function store()
    {
        request()->validate([
            'id' => 'nullable',
            'lottery_id' => 'required',
            'level' => 'required',
            'available_times' => 'required',
        ]);
        $lotteryId = request()->lottery_id;
        if (request()->id) {
            $lotteryUser = LotteryUser::query()->find(request()->id);
        } else {
            request()->validate([
                'mobile' => 'required',
            ]);
            $lottery = $this->getAgentLottery($lotteryId);
            $mobile = request()->mobile;
            $user = FrontendUser::query()
                ->where('agent_id', $lottery->agent_id)
                ->where('mobile', $mobile)
                ->first();
            if (!$user) {
                throw new AdminException('用户手机号 ' . $mobile . ' 不存在');
            }
            $existCount = LotteryUser::query()->where('lottery_id', $lotteryId)->where('user_id', $user->id)->count();
            if ($existCount > 0) {
                throw new AdminException('用户手机号 ' . $mobile . ' 已在抽奖名单中');
            }
            $lotteryUser = new LotteryUser();
            $lotteryUser->lottery_id = $lotteryId;
            $lotteryUser->user_id = $user->id;
        }

        $lotteryUser->level = request()->level;
        $lotteryUser->available_times = request()->available_times;
        $lotteryUser->save();
    }

    /** 删除抽奖用户 */
    public function destroy($userId)
    {
        $user = LotteryUser::query()->find($userId);
        if ($this->getUserDrawCount($user) > 0) {
            throw new ApiException('已参与抽奖的用户无法删除');
        }
        $user->delete();
    }

    /** 批量导入抽奖名单 */
    public function batchImport($lotteryId)
    {
        $data = UploadHelper::readExcel(request()->file('file'));
        // 检查文件头和是否有数据
        $header = array_slice($data[0], 0, 3);
        unset($data[0]);
        if ($header != ['用户手机号', '抽奖次数', '用户等级(1-5)']) {
            throw new AdminException('文件头错误，请使用指定模板上传');
        }
        if (0 == count($data)) {
            throw new AdminException('文件中不包含数据');
        }
        if (count($data) > 2000) {
            throw new AdminException('每次最多上传2000人');
        }
        $lottery = $this->getAgentLottery($lotteryId);
        if (!$lottery) {
            throw new AdminException('无效的活动ID');
        }
        $lotteryUsers = [];
        foreach ($data as $row) {
            $mobile = intval(Arr::get($row, 0));
            $availableTimes = intval(Arr::get($row, 1));
            $level = intval(Arr::get($row, 2));
            if (array_key_exists($mobile, $lotteryUsers)) {
                throw new AdminException('手机号' . $mobile . '重复');
            }
            $lotteryUsers[$mobile] = [
                'lottery_id' => $lotteryId,
                'available_times' => $availableTimes,
                'level' => $level,
                'updated_at' => now(),
                'created_at' => now(),
            ];
        }
        //查询所有用户
        /** @var AgentUser $agentUser */
        $agentUser = auth()->user();
        $userIds = FrontendUser::query()
            ->where('agent_id', $agentUser->agent_id)
            ->whereIn('mobile', array_keys($lotteryUsers))
            ->get()
            ->mapWithKeys(function (FrontendUser $user) {
                return [$user->mobile => $user->id];
            });
        foreach ($lotteryUsers as $mobile => &$lotteryUser) {
            if (!$userIds->has($mobile)) {
                throw new AdminException('手机号' . $mobile . '不存在');
            }
            $lotteryUser['user_id'] = $userIds->get($mobile);
        }
        \DB::transaction(function () use ($userIds, $lotteryUsers) {
            //先删除已经存在的用户
            LotteryUser::query()->whereIn('user_id', $userIds->values())->delete();
            //再批量添加用户
            LotteryUser::query()->insert(array_values($lotteryUsers));
        });
    }

    private function getUserDrawCount(LotteryUser $user)
    {
        return LotteryRecord::query()
            ->where('lottery_id', $user->lottery_id)
            ->where('user_id', $user->user_id)
            ->count();
    }

    private function getAgentLottery($lotteryId)
    {
        /** @var AgentUser $agentUser */
        $agentUser = auth()->user();

        return Lottery::query()->where('agent_id', $agentUser->agent_id)
            ->find($lotteryId);
    }
}
